package com.sziit.se.highconcurrency.user.application.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.sziit.se.highconcurrency.common.constant.HttpResponseCodeEnums;
import com.sziit.se.highconcurrency.common.entity.LoginRsp;
import com.sziit.se.highconcurrency.common.entity.User;
import com.sziit.se.highconcurrency.common.entity.UserInfoVo;
import com.sziit.se.highconcurrency.common.exception.CustomException;
import com.sziit.se.highconcurrency.common.tool.JwtUtils;
import com.sziit.se.highconcurrency.common.tool.LocalUser;
import com.sziit.se.highconcurrency.common.tool.PasswordUtils;
import com.sziit.se.highconcurrency.common.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sziit.se.highconcurrency.user.application.mapper.UserMapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;


import java.util.List;
import java.util.Objects;
import java.util.UUID;


import static cn.hutool.core.lang.Validator.isMobile;
import static com.sziit.se.highconcurrency.common.constant.SystemConstants.SALT;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author dongchunkeng
 * @since 2022-09-21
 */
@Service("UserService")
@AllArgsConstructor
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    private final UserMapper userMapper;

    @Override
    public List<User> getAllData() {
        return userMapper.getAllData();
    }

    @Override
    public Boolean insertUser(String userName, String password, String phone, String role) {
        String userId = UUID.randomUUID().toString();
        //生成密码
        String passwordMd5 = PasswordUtils.generate(password, SALT);
        return userMapper.insertUser(userId, userName, passwordMd5,phone, role);
    }

    @Override
    public UserInfoVo getByName(String userName) {
        User user = userMapper.getByName(userName);
        UserInfoVo userInfoVo = userInfo();
        if (!userName.equals(userInfoVo.getUserName())) {
            throw new CustomException(HttpResponseCodeEnums.FORBIDDEN.getCode(), "用户不匹配");
        }
        return userInfoVo;

    }

    @Override
    public UserInfoVo getById(String userId) {
        User user = userMapper.getById(userId);
        UserInfoVo userInfoVo = user.toVo();
        if (!userId.equals(user.getUserId())) {
            throw new CustomException(HttpResponseCodeEnums.FORBIDDEN.getCode(), "用户不匹配");
        }
        return userInfoVo;
    }

    @Override
    public Boolean register(String userName, String password, String phone) {
        if (checkPhone(phone)) {
            //生成密码
            String passwordMd5 = PasswordUtils.generate(password, SALT);
            //保存用户信息
            User user = User.builder()
                    .userId(UUID.randomUUID().toString())
                    .userName(userName)
                    .phone("手机号码" + phone)
                    .password(passwordMd5)
                    .build();
            this.save(user);
            //返回用户信息
            return true;
        } else {
            throw new CustomException("手机号码校验失败");
        }
    }

    @Override
    public LoginRsp login(String userName, String password) {
        log.info("enter login service");
        //根据用户名查询用户信息
        User user = this.lambdaQuery().eq(User::getUserName, userName).one();
        //判断用户信息是否为空
        if (user != null) {
            //判断密码是否正确
            if (PasswordUtils.matches(password, SALT, user.getPassword())) {
                //生成token
                String token = JwtUtils.sign(user.getUserName(), user.getUserId(), user.getRole());

                //返回用户信息
                return LoginRsp.builder()
                        .token(token)
                        .build();
            } else {
                throw new CustomException(HttpResponseCodeEnums.UNAUTHORIZED.getCode(),"密码错误");
            }
        } else {
            throw new CustomException(HttpResponseCodeEnums.UNAUTHORIZED.getCode(),"该用户未注册");
        }
    }

    @Override
    public UserInfoVo updateUser(String userName, String password, String phone) {
        UserInfoVo userInfoVo = LocalUser.getUserNotNull();

        UpdateWrapper<User> updateWrapper = new UpdateWrapper<User>();

        boolean phoneUserName = (userName != null && !userName.isEmpty());
        updateWrapper.set(phoneUserName, "user_name", userName);

        boolean phoneCondition = (phone != null && !phone.isEmpty());
        updateWrapper.set(phoneCondition, "phone", phone);

        boolean passwordCondition = (password != null && !password.isEmpty());
        //生成密码
        String passwordMd5 = PasswordUtils.generate(password, SALT);
        updateWrapper.set(passwordCondition, "password", passwordMd5);

        updateWrapper.eq("user_id",userInfoVo.getUserId());

        if (update(updateWrapper)) {
            // 返回用户信息
            return getById(userInfoVo.getUserId());
        } else {
            throw new CustomException(HttpResponseCodeEnums.UNAUTHORIZED.getCode(),"修改用户信息失败");
        }
    }

    @Override
    public UserInfoVo userInfo() {
        UserInfoVo userInfoVo = LocalUser.getUserNotNull();
        User user = userMapper.getById(userInfoVo.getUserId());
        if (user != null) {
            userInfoVo.setPhone(user.getPhone());
            return userInfoVo;
        } else {
            throw new CustomException(HttpResponseCodeEnums.UNAUTHORIZED.getCode(),"获取登录用户信息失败");
        }
    }


    /**
     * 判断手机号是否被注册
     *
     * @param phone 手机号
     * @return boolean
     */
    private boolean checkPhone(String phone) {
        //判断手机号是否合法
        if (isMobile(phone)) {
            //根据手机号查询用户信息
            User user = this.lambdaQuery().eq(User::getPhone, phone).one();
            //判断用户信息是否为空
            //手机号可以注册
            if (user == null) {
                return true;
            } else {
                throw new CustomException(HttpResponseCodeEnums.FORBIDDEN.getCode(),"该手机号已被注册");
            }
        }
        return false;
    }

}
